function deepClone(target, map=new Map()) {
    // 检测数据类型
    if(typeof target === 'object' && target !== null) {
        // 判单是否以及克隆过
        let cache = map.get(target);
        if(cache) {
            return cache;
        }

        // 创建一个容器
        const result = Array.isArray(target) ? [] : {};
        // 将新的结果存到map中
        map.set(target, result);

        // 遍历target
        // 如果目标数据是数组，则遍历数组
        if(Array.isArray(target)) {
            // foreach遍历
            target.forEach((item, index) => {
                result[index] = deepClone(item, map)
            })
        } else {
            // 如果目标数据是对象，则遍历对象
            Object.keys(target).forEach(key => {
                result[key] = deepClone(target[key], map)
            })
        }

        return result;
    } else {
        return target
    }
}

function deepClone2(target, map=new Map()) {
    // 检测数据类型
    if(typeof target === 'object' && target !== null) {
        // 判单是否以及克隆过
        let cache = map.get(target);
        if(cache) {
            return cache;
        }

        // 创建一个容器
        const result = Array.isArray(target) ? [] : {};
        // 将新的结果存到map中
        map.set(target, result);

        // 遍历target
        for(let key in target) {
            // 判断当前对象是否包含该属性
            if(target.hasOwnProperty(key)) {
                // 将属性设置到result中
                result[key] = deepClone2(target[key], map)
            }
        }

        return result;
    } else {
        return target
    }
}


/**
 * bug: 无法拷贝原型对象 
 */
function deepClone3(target) {
    // 递归拷贝
    // 类型判断 {} [] null
    if (typeof target === 'object' && target !== null) {
        // 创建一个容器
        const result = Array.isArray(target) ? [] : {};
        // 遍历target
        for(let key in target) {
            // 判断当前对象是否包含该属性
            if(target.hasOwnProperty(key)) {
                // 将属性设置到result中
                result[key] = deepClone3(target[key])
            }
        }

        return result;
    }
}



/**
 * bug: 无法克隆函数
 * bug: 无法克隆正则
 * bug: 无法克隆日期
 * bug: 无法克隆循环引用
 */
function deepClone4(target) {
    // 通过数据创建JSON格式的字符串
    const str = JSON.stringify(target);

    // 将JSON格式的字符串转换为JS对象
    const data = JSON.parse(str);

    return data;
}